import { MoveType, SCREEN_Y } from "./MoveConfig";
import MoveCollide from "./MoveCollide";
import { EVector3 } from "../engine/Math";
import { MoveTopCollide } from "./MoveTopCollide";
import { IMoveShape } from "./IMoveShape";
import { IMoveObject } from "./IMoveObject";
import { IMoveWorld } from "./IMoveWorld";
function getVy(a: number, s: number): number {
    let h = 0;
    let v0 = 0;
    if (a > 0) {
        while (h < s) {
            v0 += a;
            h += v0;
        }
    }
    return v0
}
export class MoveBody {

    protected object: IMoveObject = null;

    constructor(obj: IMoveObject) {
        this.object = obj;
    }

    protected collide: MoveCollide;

    protected _topCollide: MoveTopCollide;

    protected _world: IMoveWorld;


    setWorld(w: IMoveWorld) {
        this._world = w;
    }

    b: MoveBody[] = [];

    //是否活动 比如固定的平台，是不活动的
    private _awake: boolean = true;

    //是否可用
    private _active: boolean = true;

    //是否参与缩放
    scale: boolean = true;

    //是否更新位置
    updatePos: boolean = true;

    //速度
    private _speed: EVector3 = new EVector3(0, 0, 0)

    //角色在地图中的位置
    position: EVector3 = new EVector3(0, 0, 0)

    //宽高纵深
    size: EVector3 = new EVector3(0, 0, 20)

    // 弹力
    protected _elasticity: number = 0;
    //摩擦力
    protected frictional: number = 0;

    //跳跃高度
    jumpHigh: number = 350;

    shape: IMoveShape
    //左右移动方向
    // protected moveXDir: DIR = DIR.RIGHT;
    // //上下移动方向
    // protected moveZDir: DIR = DIR.UP;

    protected moveType: MoveType = MoveType.OBJECT;
    protected maxY: number = -1;

    protected minY: number = -1;

    // protected onGroundFlag: boolean = true;

    getB(): MoveBody[] {
        return this.b;
    }

    setMoveType(type: MoveType) {
        this.moveType = type;
    }


    setSpeed(x: EVector3): void
    setSpeed(x: any, y?: number, z?: number): void {
        if (y && z) {
            this.setSpeedX(x)
            this.setSpeedY(y)
            this.setSpeedZ(z)
        } else {
            this.setSpeedX(x.x)
            this.setSpeedY(x.y)
            this.setSpeedZ(x.z)
        }
    }

    getSpeed(): EVector3 {
        return this._speed;
    }

    getWorldPosition(){
        return this.object.getWorldPosition()
    }

    protected _standType: MoveType = MoveType.GROUND


    getMoveType(): MoveType {
        return this.moveType;
    }

    getPosition() {
        return this.position;
    }

    getStandType() {
        return this._standType;
    }

    setStandType(t: MoveType) {
        this._standType = t;
        if (this.isStopDrop()) {
            if (this.getTopCollide()) {
                this.getTopCollide().onTopExit()
            }
        }
    }

    getShap(): IMoveShape {
        return this.shape;
    }


    getLeft() {
        return this.getX() - this.getAnchorX() * this.getWidth();
    }

    getRight() {
        return this.getX() + (1 - this.getAnchorX()) * this.getWidth();
    }

    getMidY() {
        return this.getY() + SCREEN_Y * (this.getAnchorY() * this.getHeight()) / 2
    }

    getMidX() {
        return this.getX() + (1 - this.getAnchorX()) * this.getWidth() / 2;
    }

    getTop() {
        return this.getY() + SCREEN_Y * (1 - this.getAnchorY()) * this.getHeight();
    }

    getBottom() {
        return this.getY() - SCREEN_Y * this.getAnchorY() * this.getHeight();
    }

    getInner() {
        return this.getZ() + 0.5 * this.getDepth();
    }

    getOutter() {
        return this.getZ() - 0.5 * this.getDepth();
    }


    setCollide(c: MoveCollide) {
        this.collide = c;
    }

    getCollide() {
        return this.collide;
    }

    setTopCollide(top: MoveTopCollide) {
        this._topCollide = top;
    }

    getTopCollide() {
        return this._topCollide;
    }



    isScale() {
        return this.scale;
    }

    isUpdatePos() {
        return this.updatePos
    }

    setActive(f: boolean) {
        this._active = f;
    }

    isActive() {
        return this._active;
    }



    getFrictional() {
        return this.frictional;
    }

    setFrictional(n: number) {
        this.frictional = n;
    }

    setElasticity(n: number) {
        this._elasticity = n;
    }

    getElasticity() {
        return this._elasticity;
    }

    isAwake() {
        return this._awake
    }

    setAwake(f: boolean) {
        this._awake = f;
    }

    getJumpHigh() {
        return this.jumpHigh;
    }
    setJumpHight(h: number) {
        this.jumpHigh = h;
    }


    jump(h: number) {
        let spy = getVy(this._world.getG(), h);
        // console.log(' jump spy ', spy, h)
        this.setStandType(MoveType.OBJECT)
        this.setSpeedY(spy)
    }


    // isJumping() {
    //     return this.position.y > 0
    // }
    setX(x: number) {
        this.position.x = x;
    }

    getMinY() {
        return this.minY;
    }

    getMaxY() {
        return this.maxY;
    }

    setY(y: number) {
        this.position.y = y;
        if (this.minY == -1) {
            this.minY = y;
        } else if (y < this.minY) {
            this.minY = y;
        }
        if (this.maxY == -1) {
            this.maxY = y;
        } else if (y > this.maxY) {
            this.maxY = y;
        }
    }

    getZ() {
        return this.position.z;
    }

    setZ(z: number) {
        this.position.z = z;
    }

    // updateZIndex() {
    //     this.setZIndex(-this.getZ())
    // }

    getX() {
        return this.position.x;
    }

    getY() {
        return this.position.y;
    }


    getSpeedX() {
        return this._speed.x
    }

    setSpeedX(s: number) {
        this._speed.x = s;
    }

    setSpeedY(spy: number) {
        this._speed.y = spy;
    }

    getSpeedY() {
        return this._speed.y
    }

    setSpeedZ(z: number) {
        this._speed.z = z;
    }

    getSpeedZ() {
        return this._speed.z;
    }

    isOnGround() {
        return this.getStandType() == MoveType.GROUND;
    }

    isOnPlane() {
        return this.getStandType() == MoveType.PLANE;
    }

    isStopDrop() {
        return this.getStandType() != MoveType.OBJECT;
    }


    setPosition(x: number, y: number, z: number) {
        // console.log(' setPosition ', x, y, z)
        this.setX(x)
        this.setZ(z)
        // let sy = y - z;
        // if (sy < 0) {
        //     sy = 0
        // }
        this.setY(y)
    }

    getWidth() {
        if (this.size.x == 0) {
            this.setWidth(this.getNodeWidth())
        }
        return this.size.x;
    }

    getHeight() {
        if (this.size.y == 0) {
            this.setHeight(this.getNodeHeight())
        }
        return this.size.y
    }

    getDepth() {
        return this.size.z;
    }

    setWidth(w: number) {
        this.size.x = w;
    }

    setHeight(h: number) {
        this.size.y = h;
    }

    setDepth(z: number) {
        this.size.z = z;
    }
    //  setZIndex(i: number): void
    setVisible(f: boolean): void {
        this.object.setVisible(f)
    }
    isVisible(): boolean {
        return this.object.isVisible()
    }


    getAnchorX(): number {
        return this.object.getAnchorX();
    }
    getAnchorY(): number {
        return this.object.getAnchorY();
    }
    getScale(): number {
        return this.object.getScale();
    }
    setScale(s: number): void {
        this.object.setScale(s)
    }
    setNodeX(x: number): void {
        this.object.setNodeX(x)
    }
    setNodeY(y: number): void {
        this.object.setNodeY(y)
    }
    getNodeWidth(): number {
        return this.object.getNodeWidth();
    }
    getNodeHeight(): number {
        return this.object.getNodeHeight();
    }
}